package com.zis.platform.core.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.zis.common.SearchParams;
import com.zis.platform.common.service.impl.BaseServiceImpl;
import com.zis.platform.common.web.TreeNode;
import com.zis.platform.core.dao.OrgDao;
import com.zis.platform.core.entity.OrgEntity;
import com.zis.platform.core.service.OrgService;
import com.zis.util.StringUtil;

@Service
public class OrgServiceImpl extends BaseServiceImpl<OrgEntity> implements OrgService
{
    @Autowired
    OrgDao orgDao;
    
    @Override
    public List<OrgEntity> findByCondition(SearchParams params)
        throws Exception
    {
        return orgDao.findByCondition(params);
    }
    
    @Override
    public List<OrgEntity> findAll()
        throws Exception
    {
        return orgDao.findAll();
    }
    
    @Override
    public List<OrgEntity> findByParentId(String parentId)
    {
        List<OrgEntity> list = orgDao.findByParentId(parentId);
        for (OrgEntity db : list)
        {
            db.setIsParent(this.orgDao.findCountByParentId(db.getOrgId()) > 0);
        }
        return list;
    }
    
    @Override
    public int deleteByOrgIds(String[] orgIds)
    {
        return this.orgDao.deleteByOrgIds(orgIds);
    }
    
    @Override
    public OrgEntity saveOrUpdate(OrgEntity org)
    {
        if (org != null)
        {
            if (StringUtils.isBlank(org.getOrgId()))
            {
                org.setOrgId(UUID.randomUUID().toString());
                int insertNum = orgDao.insertSelective(org);
                if (insertNum > 0)
                {
                    return org;
                }
            }
            else
            {
                int updateNum = orgDao.updateByPrimaryKeySelective(org);
                if (updateNum > 0)
                {
                    return org;
                }
            }
        }
        return null;
    }
    
    @Override
    public List<OrgEntity> findAllChildrenByParentId(String parentId)
    {
        List<OrgEntity> list = orgDao.findByParentId(parentId);
        for (OrgEntity db : list)
        {
            List<OrgEntity> children = findAllChildrenByParentId(db.getOrgId());
            if (children != null && children.size() > 0)
            {
                db.setIsParent(true);
                db.setChildren(children);
            }
            else
            {
                db.setIsParent(false);
            }
        }
        return list;
    }
    
    @Override
    public List<TreeNode> findRoot()
    {
        List<OrgEntity> list = orgDao.findRoot();
        List<TreeNode> treeNodeList = new ArrayList<TreeNode>();
        Map<String, TreeNode> map = new HashMap<String, TreeNode>(list.size());
        for (OrgEntity org : list)
        {
            TreeNode node = new TreeNode(org.getOrgId(), org.getOrgName(), org.getParentOrgId());
            treeNodeList.add(node);
            map.put(node.getId(), node);
        }
        List<TreeNode> rootNodeList = new ArrayList<TreeNode>();
        for (TreeNode node : treeNodeList)
        {
            if (StringUtil.isEmpty(node.getParentId()))
            {
                rootNodeList.add(node);
                continue;
            }
            TreeNode parent = map.get(node.getParentId());
            if (parent == null)
            {
                rootNodeList.add(node);
            }
        }
        treeNodeList.removeAll(rootNodeList);
        for (TreeNode node : rootNodeList)
        {
            initChildren(node, treeNodeList);
        }
        return rootNodeList;
    }
    
    private void initChildren(TreeNode org, List<TreeNode> list)
    {
        List<TreeNode> nodelist = new ArrayList<TreeNode>();
        for (TreeNode _org : list)
        {
            if (StringUtil.isNotEmpty(_org.getParentId()) && _org.getParentId().equalsIgnoreCase(org.getId()))
            {
                nodelist.add(_org);
            }
        }
        if (nodelist.size() > 0)
        {
            org.setChildren(nodelist);
            org.setState("closed");
            list.removeAll(nodelist);
            for (TreeNode _org : nodelist)
            {
                initChildren(_org, list);
            }
        }
    }
}
